﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cos.Admin;
using Cos.Core.Interception;
using Cos.Core.Model.Common;
using Cos.Core.Model.Content;
using Cos.Core.Model.Template;
using Cos.Core.NHibernate;
using Cos.Core.Service;
using Cos.Module.CMS;
using Cos.Module.CMS.Data;
using Cos.Module.CMS.NHibernate;
using Cos.Module.Configuration;
using Cos.Module.Configuration.Data;
using Cos.Module.Configuration.NHibernate;
using Cos.Module.Media;
using Cos.Module.Media.Data;
using Cos.Module.Media.NHibernate;
using Cos.Module.Membership;
using Cos.Module.Membership.Data;
using Cos.Module.Membership.NHibernate;
using Cos.Module.Template;
using Cos.Module.Template.Data;
using Cos.Module.Template.NHibernate;
using FluentNHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using Microsoft.Practices.Unity;
using NHibernate;
using NHibernate.Context;
using NUnit.Framework;

namespace Alogient.Cameleon.Sdk.tests
{
    [TestFixture]
    public class FixtureBase
    {
        [TestFixtureSetUp]
        public void FixtureSetup()
        {
            // create dependency container
            var container = new UnityContainer();
            container.AddNewExtension<InterceptOnRegisterContainerExtension>();

            container.RegisterType<ICultureService, CultureService>()
                .RegisterType<INavRepository, NavRepository>()
                .RegisterType<IPageService, PageService>()
                .RegisterType<IPageRepository, PageRepository>()
                .RegisterType<IElementRepository, ElementRepository>()
                .RegisterType<ISiteService, SiteService>()
                .RegisterType<IMembershipService, MembershipService>()
                .RegisterType<IMembershipRepository, MembershipRepository>()
                .RegisterType<ICultureRepository, CultureRepository>()
                .RegisterType<IMediaRepository, MediaRepository>()
                .RegisterType<ITemplateService, TemplateService>()
                .RegisterType<ITemplateRepository, TemplateRepository>()
                .RegisterType<IPartRepository, PartRepository>()
                .RegisterType<IDataTypeRepository, DataTypeRepository>()
                .RegisterType<ISiteRepository, SiteRepository>()
                .RegisterType<IMediaService, MediaService>()
                .RegisterType<IMediaRepository, MediaRepository>()
                .RegisterType<ISessionFactory>(new ContainerControlledLifetimeManager(),
                new InjectionFactory(
                    c => 
                        {
                            var nhibernateConfiguration = new NHibernate.Cfg.Configuration();

                            nhibernateConfiguration.SetProperty("hbm2ddl.auto", "validate");

                            var cfg = Fluently.Configure(nhibernateConfiguration)
                           .Database(MsSqlConfiguration.MsSql2008
                               .ConnectionString(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\FullDatabase.mdf;Integrated Security=True;User Instance=True").ShowSql().CurrentSessionContext<ThreadLocalSessionContext>());

                            var model = new PersistenceModel();
                            model.AddMappingsFromAssembly(typeof(PageDataModel).Assembly);
                            var sessionSource = new SessionSource(cfg.BuildConfiguration().Properties, model);
                            
                            return sessionSource.Configuration.BuildSessionFactory();
                        }));

            ServiceLocator.Container = container;

            this.AddDefaultData();
        }

        [TestFixtureTearDown]
        public void FixtureTearDown()
        {

        }

        public const string frCultureCode = "fr-CA";
        public const string enCultureCode = "en-CA";
        public const string basicTemplateName = "Basic template";
        public const string basicPartName = "part";
        public const string mediaPartName = "partMedia";
        public const string imagePartName = "partImage";
        public const string associationPartName = "partAssociation";
        public int navID;

        protected void AddDefaultData()
        {
            var cultureService = ServiceLocator.Get<ICultureService>();

            // Cultures
            var frCulture = new Culture
                                {
                                    CultureCode = frCultureCode,
                                    CultureDesc = "francais",
                                    IsDefaultCulture = true
                                };

            var enCulture = new Culture
                                {
                                    CultureCode = enCultureCode,
                                    CultureDesc = "english",
                                    IsDefaultCulture = false
                                };

            frCulture = cultureService.SaveCulture(frCulture);
            enCulture = cultureService.SaveCulture(enCulture);

            // Template Service
             var templateService = ServiceLocator.Get<ITemplateService>();

            // DataType
            var dataTypeText = templateService.GetDataType(1);
            if (dataTypeText == null)
            {
                dataTypeText = new DataType
                               {
                                   HasMedia = false,
                                   IsFormField = false,
                                   Name = "Text"
                               };

                dataTypeText = templateService.SaveDataType(dataTypeText);
            }

            var dataTypeMedia = templateService.GetDataType(2);
            if (dataTypeMedia == null)
            {
                dataTypeMedia = new DataType
                                    {
                                        HasMedia = true,
                                        IsFormField = false,
                                        Name = "Media"
                                    };

                dataTypeMedia = templateService.SaveDataType(dataTypeMedia);
            }

            var dataTypeImage = templateService.GetDataType(3);
            if (dataTypeImage == null)
            {
                dataTypeImage = new DataType
                                    {
                                        HasMedia = true,
                                        IsFormField = false,
                                        Name = "Image"
                                    };

                dataTypeImage = templateService.SaveDataType(dataTypeImage);
            }

            var dataTypeAssociation = templateService.GetDataType(4);
            if (dataTypeAssociation == null)
            {
                dataTypeAssociation = new DataType
                                          {
                                              HasMedia = false,
                                              IsFormField = false,
                                              Name = "Association"
                                          };
                dataTypeAssociation = templateService.SaveDataType(dataTypeAssociation);
            }

            // Template
            var template = templateService.GetTemplate(1);
            if (template == null)
            {
                template = new Cos.Core.Model.Template.Template
                               {
                                   IsListView = false,
                                   TemplateName = basicTemplateName,
                                   TemplateUrl = "test.aspx"
                               };

                template = templateService.SaveTemplate(template);
            }

            // Part
            var parts = templateService.GetParts(template.TemplateId);
            if (parts.Count() == 0)
            {
                var part1 = new Part
                               {
                                    IsMultiCulture = true,
                                    IsRequired = false,
                                    PartName = basicPartName,
                                    PartOrder = 1,
                                    TemplateId = template.TemplateId,
                                    DataTypeId = dataTypeText.Id
                               };

                templateService.SavePart(part1);

                var part2 = new Part
                                {
                                    DataTypeId = dataTypeImage.Id,
                                    IsMultiCulture = true,
                                    IsRequired = false,
                                    PartName = imagePartName,
                                    PartOrder = 2,
                                    TemplateId = template.TemplateId
                                };

                templateService.SavePart(part2);

                var part3 = new Part
                                {
                                    DataTypeId = dataTypeMedia.Id,
                                    IsMultiCulture = true,
                                    IsRequired = false,
                                    PartName = mediaPartName,
                                    PartOrder = 3,
                                    TemplateId = template.TemplateId
                                };

                templateService.SavePart(part3);

                var part4 = new Part
                                {
                                    DataTypeId = dataTypeAssociation.Id,
                                    IsMultiCulture = true,
                                    IsRequired = false,
                                    PartName = associationPartName,
                                    PartOrder = 4,
                                    TemplateId = template.TemplateId
                                };

                templateService.SavePart(part4);
            }

            // Pages
            var pageService = ServiceLocator.Get<PageService>();
            var nav = pageService.GetNav(1);
            var page = pageService.GetPage(frCulture, 1);
            if (nav == null)
            {
                nav = new Nav
                          {
                              TemplateId = template.TemplateId,
                              InheritPermissions = true,
                              NavOrder = 1,
                              ParentNavId = 0
                          };

                page = new Page
                               {
                                   ApprobationDate = DateTime.Now,
                                   Author = "test",
                                   CreationDate = DateTime.Now,
                                   CultureCode = frCulture.CultureCode,
                                   LastModified = DateTime.Now,
                                   PageName = "test",
                                   PageNamePreview = "test preview",
                                   PageNavEnd = false,
                                   PageStatus = "Pending",
                                   PageVisibility = true,
                                   PageVisibilityPreview = true
                               };

                page = pageService.SavePage(nav, page, null);
            }

            this.navID = page.NavId;

            if (page != null)
            {
                var elements = pageService.GetElements(page.PageId);

                var element = elements.Where(e => e.PartId == 1).First();
                element.Value = "test";
                element.PreviewValue = "test";
                pageService.SaveElement(element);

                element = elements.Where(e => e.PartId == 2).First();
                element.Value = "image";
                element.PreviewValue = "image";
                element.File = "test.jpg";
                element.PreviewFile = "test.jpg";
                pageService.SaveElement(element);

                element = elements.Where(e => e.PartId == 3).First();
                element.Value = "media";
                element.PreviewValue = "media";
                element.File = "test.jpg";
                element.PreviewFile = "test.jpg";
                pageService.SaveElement(element);

                element = elements.Where(e => e.PartId == 4).First();
                element.Value = page.NavId.ToString();
                element.PreviewValue = page.NavId.ToString();
                pageService.SaveElement(element);
            }
        }
    }
}
